#include <ESP8266WiFi.h>
#include "ELMduino.h"
#include <SoftwareSerial.h>
#include <LedControl.h>
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
#define PIN D2
#define BRIGHTNESS 20 // 设置灯光亮度
#define ELM_PORT Serial1
int DIN = D5;
int CS =  D6;
int CLK = D7; 
    LedControl lc=LedControl(DIN,CLK,CS,0);
   byte R[8]={0xFC,0x66,0x66,0x6E,0x7C,0x7C,0x6E,0xE7};/*"R",0*/
    byte kn[8]={0xC3,0xE3,0xF3,0xDB,0xDB,0xCF,0xC7,0xC3};/*"n",0*/ 
    byte one[8]={0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18};/*"1",0*/
    byte tow[8]={0x3C,0x7E,0x42,0x1E,0x3C,0x60,0x7E,0x7E};/*"2",0*/
    byte sui[8]={0x3C,0x7E,0x46,0x1C,0x1C,0x46,0x7E,0x3C};/*"3",0*/
    byte four[8]={0x0C,0x1C,0x3C,0x6C,0xFF,0xFF,0x0C,0x0C};/*"4",0*/
    byte five[8]={0x7E,0x7E,0x60,0x7C,0x06,0x66,0x7E,0x3C};/*"5",0*/
    byte six[8]={0x3C,0x7E,0x60,0x7C,0x7E,0x66,0x7E,0x3C};/*"6",0*/
    byte seven[8]={0x00,0xFE,0xFE,0x0C,0x18,0x18,0x18,0x18};/*"6",0*/
    byte full[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/*"0",0*/
    byte off[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/*"6",0*/

const char* ssid = "WIFI_OBDII";
const char* password = "your-password";

//IP Adress of your ELM327 Dongle
IPAddress server(192, 168, 0, 10);
WiFiClient client;
ELM327 myELM327;

typedef enum { ENG_RPM,SPEED,COOL} obd_pid_states;
obd_pid_states obd_state = ENG_RPM;
float rpm = 0;
float kph = 0;
int Z = 0; 
int x = 0;
int d = 0;
int j;
int i;
#define NUMPIXELS 10//流水灯数量
 
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

const int ledPin = D8; // LED 连接到 D2 引脚
const int keyPin = D4; // 按键连接到 D4 引脚
 
volatile bool flag = false; // 记录 LED 状态的标志
 
// 外部中断处理函数
ICACHE_RAM_ATTR void handleInterrupt() {
      flag = !flag; // 切换 LED 状态
}
 
void setup() {
  pixels.begin();
    Serial.begin(230400);
   pixels.setBrightness(BRIGHTNESS); // 设置灯光亮度
  lc.shutdown(0,false);
  lc.setIntensity(0,2);      //调整最大亮度为 15
  lc.clearDisplay(0); 
  int hue = 0; // 初始化色相值

  // 先熄灭所有灯
  for (int i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, 0); // 关闭所有灯
  }
  pixels.show(); // 显示熄灭效果
  delay(100); // 延迟一段时间

  // 依次点亮彩色渐变循环流水灯
  for (int i = 0; i < NUMPIXELS; i++) {
    int pixelColor = pixels.ColorHSV(hue); // 根据色相值获取彩色
    pixels.setPixelColor(i, pixelColor); // 设置每颗灯的颜色
    hue += 655360/180; // 色相值增加，实现彩色渐变循环
    pixels.show(); // 显示灯光效果
    
    delay(50); // 延迟一段时间
  }
  // Connecting to ELM327 WiFi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  printByte(kn);
  WiFi.mode(WIFI_AP);
  WiFi.begin(ssid);
  // WiFi.begin(ssid, password); //Use this line if your ELM327 has a password protected WiFi

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Connected to Wifi");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  if (client.connect(server, 35000))
    Serial.println("connected");
  else
  {
    Serial.println("connection failed");
    ESP.reset();
  }
  myELM327.begin(client, true, 2000);
  
  
  pinMode(ledPin, OUTPUT);      // 设置 LED 引脚为输出模式
  pinMode(keyPin, INPUT);// 设置按键引脚为输入模式，并启用上拉电阻
 
  attachInterrupt(digitalPinToInterrupt(keyPin), handleInterrupt, FALLING); // 设置外部中断
}
 
void loop() {
  switch (obd_state)
  { 
    case ENG_RPM:
    {
      rpm = myELM327.rpm();
      
      if (myELM327.nb_rx_state == ELM_SUCCESS)
      { 
       Z=rpm/1000;
      for (j = 0; j < Z; j++) {
      if(Z<7){pixels.setPixelColor(j, pixels.Color(Z*40, 210/Z, 0)); // 依次点亮灯
        pixels.show(); // 显示灯光效果
     delay(5);
     }
     else {
      printByte(full);
      pixels.fill(pixels.Color(255, 0, 0), 0, NUMPIXELS);
      pixels.show();
      delay(10); // 等待一段时间
      printByte(off);
      pixels.clear();
      pixels.show();
      delay(15); // 等待一段时间

     }
  }
  
  for (i = 10 - 1; i >= Z; i--) {
    pixels.setPixelColor(i, 0); // 从右往左依次熄灭
    pixels.show(); // 显示灯光效果
    delay(10);
  }
 
       obd_state = SPEED;
      }
      else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
      {
        myELM327.printError();
         ESP.reset();
        obd_state = SPEED;
      }
      
      break;
    }
    case SPEED:
    {
      kph = myELM327.kph();
      
      if (myELM327.nb_rx_state == ELM_SUCCESS)
      {
      d = rpm/kph;
    if(d>=99&&d<128)
	{
	  printByte(one);
	}
	else if(d>=65&&d<78)
	{
	     printByte(tow);
	}
	else if(d>=46&&d<55)
	{
		printByte(sui);
	}
	else if(d>=37&&d<43)
	{
	printByte(four);
	}
else if(d>=31&&d<37)
	{
	printByte(five);
	}

else if(d>=23&&d<28)
	{
	printByte(six);
	}
	else{
		printByte(kn);

	}

       obd_state = ENG_RPM;

      }
      else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
      {
        myELM327.printError();
       ESP.reset();
      }
      
      break;
    }
  }
  }






void printByte(byte character [])
{
  int i = 0;
  for(i=0;i<8;i++)
  {
    lc.setRow(0,i,character[i]);
  }
}

